package com.liang.WebSocketChat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liang.common.lang.Message;
import com.liang.common.lang.OnlineUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @name: WebSocketServer
 * @author: 李昂
 * @date: 2020-12-14 17:25
 * @description：WebSocketServer
 * @update: 2020-12-14 17:25
 */

@Slf4j
@Component
@ServerEndpoint("/chat")
public class WebSocketServer {

    /**
     * concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
     */
    private static ConcurrentHashMap<String, Session> webSocketMap = new ConcurrentHashMap<>();

    /**
     * 在线用户
     */
    private static ConcurrentHashMap<String, OnlineUser> onlineUserMap = new ConcurrentHashMap<>();

    private static List<OnlineUser> list = new ArrayList<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws IOException {
        //map里面的数量就是在线人数
        webSocketMap.put(session.getId(), session);
        log.info("用户连接:" + session.getId() + ",当前在线人数为:" + webSocketMap.size());
        try {
            list.clear();
            onlineUserMap.forEach((key, val) -> {
                list.add(val);
            });
            session.getBasicRemote().sendText(Message.jsonStr("enter", session.getId(), JSONObject.toJSONString(list), webSocketMap.size()));
        } catch (IOException e) {
            throw new IOException("抱歉您未连接上聊天室");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        if (webSocketMap.containsKey(session.getId())) {
            webSocketMap.remove(session.getId());
            JSONObject jsonObject = new JSONObject();
            OnlineUser user = onlineUserMap.get(session.getId());

            //从用户列表中删除
            onlineUserMap.remove(session.getId());

            jsonObject.put("id", user.getId());
            jsonObject.put("anonymous", user.getAnonymous());
            sendMessageToAll(Message.jsonStr("quit", session.getId(), jsonObject.toJSONString(), webSocketMap.size()));
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:" + session.getId() + ",报文:" + message);
        if (message != null) {
            try {
                //解析发送的报文
                JSONObject jsonObject = JSON.parseObject(message);
                String userId = jsonObject.getString("userId");
                String avator = jsonObject.getString("avator");
                String username = jsonObject.getString("username");
                String remark = jsonObject.getString("remark");
                String id = jsonObject.getString("id");
                String anonymous = jsonObject.getString("anonymous");
                String onlineCount = jsonObject.getString("onlineCount");

                onlineUserMap.put(userId, new OnlineUser(userId, avator, username, remark, id, anonymous));
                sendMessageToAll(OnlineUser.jsonStr(userId, avator, username, remark, id, anonymous, onlineCount, "online"));

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:" + session.getId() + ",原因:" + error.getMessage());
        error.printStackTrace();
    }


    /**
     * 发送自定义消息
     */
    public static void sendInfo(String message, String toUserid) throws IOException {
        log.info("发送消息到:" + toUserid + "，报文:" + message);
        if (webSocketMap.containsKey(toUserid)) {
            webSocketMap.get(toUserid).getBasicRemote().sendText(message);
        } else {
            log.error("用户" + toUserid + ",不在线！");
        }
    }

    /**
     * 公共方法：发送信息给所有人
     */
    public static void sendMessageToAll(String msg) {
        webSocketMap.forEach((id, session) -> {
            try {
                session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

}
